using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.Common;

namespace DAL
{
   
    public class Table<TEntity>:IChild<DataBase>
    {
        protected Type spTypeGetAll;
        protected Type spTypeGetMany;
        protected Type spTypeGetOne;
        protected Type spTypeRemove;
        protected Type spTypeAdd;
        protected Type spTypeSave;
       

        private DataBase _db = null;
        public DataBase db
        {
            get
            {
                return _db;
            }
        }

        public void SetParent(DataBase p)
        {
            _db = (DataBase)p;

            string SpNamePrefix = "sp";
            string SpNameSeparator = "_";
            string SpNameGetAll = "GetAll";
            string SpNameGetMany = "GetMany";
            string SpNameGetOne = "GetOne";
            string SpNameAdd = "Add";
            string SpNameSave = "Save";
            string SpNameRemove = "Remove";

          
            spNamePrefix prefix = Reflector.GetClassAttribute<spNamePrefix>(p);
            if (prefix != null)
                SpNamePrefix = prefix.Text; 
            
            spNameSeparator separator = Reflector.GetClassAttribute<spNameSeparator>(p);
            if (separator != null)
                SpNameSeparator = separator.Text;

            spNameGetAll GetAll = Reflector.GetClassAttribute<spNameGetAll>(p);
            if (GetAll != null)
                SpNameGetAll = GetAll.Text;

            spNameGetMany GetMany = Reflector.GetClassAttribute<spNameGetMany>(p);
            if (GetMany != null)
                SpNameGetMany = GetMany.Text;

            spNameGetOne GetOne = Reflector.GetClassAttribute<spNameGetOne>(p);
            if (GetOne != null)
                SpNameGetOne = GetOne.Text;

            spNameAdd Add = Reflector.GetClassAttribute<spNameAdd>(p);
            if (Add != null)
                SpNameAdd = Add.Text;

            spNameSave Save = Reflector.GetClassAttribute<spNameSave>(p);
            if (Save != null)
                SpNameSave = Save.Text;

            spNameRemove Remove = Reflector.GetClassAttribute<spNameRemove>(p);
            if (Remove != null)
                SpNameRemove = Remove.Text;


            spTypeGetAll = Reflector.GetSPType<TEntity, spGetAll>(this, SpNamePrefix, SpNameGetAll, SpNameSeparator);
            spTypeGetMany = Reflector.GetSPType<TEntity, spGetMany>(this, SpNamePrefix, SpNameGetMany, SpNameSeparator);
           
            spTypeGetOne = Reflector.GetSPType<TEntity, spGetOne>(this, SpNamePrefix, SpNameGetOne, SpNameSeparator);
            spTypeSave = Reflector.GetSPType<TEntity, spSave>(this, SpNamePrefix, SpNameSave, SpNameSeparator);
            spTypeAdd = Reflector.GetSPType<TEntity, spAdd>(this, SpNamePrefix, SpNameAdd, SpNameSeparator);
            spTypeRemove = Reflector.GetSPType<TEntity, spRemove>(this, SpNamePrefix, SpNameRemove, SpNameSeparator);
                
    

        }

        private string _TableName = null;
        public string TableName
        {
            get
            {
                return _TableName;
            }
        }


       

        public Table()
        {
            try
            {
               
                
                TableName tn = Reflector.GetClassAttribute<TableName>(this);
                if (tn != null)
                {
                    _TableName = tn.Name;
                }
                else
                {
                    _TableName = this.GetType().Name;
                }



        }
            catch (Exception exp)
            {
                throw new DbException(DbExceptionType.InitTables, exp);
            }
        }
        public virtual List<TEntity> GetManyPaged(IPager pager, params object[] Filter)
        {

            return db.Execute<TEntity>(spTypeGetMany, pager, Filter);

            
        }


        public virtual List<TEntity> GetMany(params object[] Filter)
        {
            return db.Execute<TEntity>(spTypeGetMany, Filter);
        }


        public virtual List<TEntity> GetAllPaged(IPager pager, params object[] Filter)
        {
            return  db.Execute<TEntity>(spTypeGetAll,pager, Filter);

        }
        
       
        public virtual List<TEntity> GetAll(params object [] Filter)
        {
            return db.Execute<TEntity>(spTypeGetAll, Filter);
        }


        public virtual TEntity GetOne(params object[] Filter)
        {
            return db.ExecuteOne<TEntity>(spTypeGetOne, Filter);
        }
             
       

        public virtual void  Add(TEntity obj)
        {
             db.Execute(spTypeAdd, obj);
        }

        public virtual void  Save(TEntity obj)
        {
             db.Execute(spTypeSave, obj);
        }

        
        public virtual void Remove(params object[] obj)
        {
            db.Execute(spTypeRemove, obj);
        }
   
     /*   public List<TEntity> SelectList(StoredProcedure sp)
        {
            return db.Execute<TEntity>(sp);
        }
        public TEntity SelectOne(StoredProcedure sp)
        {
            return db.ExecuteOne<TEntity>(sp);
        }
        public int Exec(StoredProcedure sp)
        {
            return db.Execute(sp);
        }*/


    }
}
